package com.fram.common.util.qiniu;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.fram.common.canstant.PublicConstant;
import com.fram.common.exception.ProException;
import com.fram.common.util.PublicMethod;
import com.fram.common.util.date.DateUtils;
import com.fram.common.util.json.JSONTools;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;

@Component
@EnableAsync
public class QiniuUtils {

	@Autowired
	private QiNiuConfig config;

	public static Logger LOG = LoggerFactory.getLogger(QiniuUtils.class);

	private Auth connectQiniu() {
		Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
		return auth;
	}

	public String getUpToken() {
		Auth auth = connectQiniu();
		if (auth == null) {
			return null;
		}
		return auth.uploadToken(config.getBucketName());
	}

	/**
	 * 
	 * @description：-> 上传网络图片到七牛
	 * 
	 * @param imageUrl
	 * @param filePath
	 *            上传地址
	 * @return
	 *
	 * @作者：陳曉鬆
	 * @时间：2018年4月3日 下午4:30:43 @版本：V1.0
	 *
	 */
	public String uploadUrlImage(String imageUrl, String fileName) {
		// 构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(Region.region0());
		// ...其他参数参考类注释
		UploadManager uploadManager = new UploadManager(cfg);
		try {
			/* 将网络资源地址传给,即赋值给url */
			URL url = new URL(imageUrl);
			/* 此为联系获得网络资源的固定格式用法，以便后面的in变量获得url截取网络资源的输入流 */
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			DataInputStream byteInputStream = new DataInputStream(connection.getInputStream());
			Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
			String upToken = auth.uploadToken(config.getBucketName());
			Response response = uploadManager.put(byteInputStream, fileName, upToken, null, null);
			// 解析上传成功的结果
			DefaultPutRet putRet = JSONTools.jsonStr2obj(response.bodyString(), DefaultPutRet.class);
			LOG.info("-七牛上传:{}", response.bodyString());
			return config.fileDomain + putRet.key;
		} catch (Exception ex) {
			ex.printStackTrace();
			return "上传失败";
		}
	}

	/**
	 * 普通上传
	 *
	 * @param filePath
	 * @param fileName
	 *            七牛云访问地址
	 * @throws IOException
	 */
	public QiniuUploadResponse upload(Object filePath, String fileName) throws ProException {
		Configuration cfg = new Configuration(Region.region0());
		// 创建上传对象
		UploadManager uploadManager = new UploadManager(cfg);
		try {
			// 调用put方法上传
			Response res;
			Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
			String upToken = auth.uploadToken(config.getBucketName());
			QiniuUploadResponse resoponse = null;
			if (filePath instanceof byte[]) {
				res = uploadManager.put((byte[]) filePath, fileName, upToken);
				LOG.info("-七牛上传:{}", res.bodyString());
				resoponse = JSONTools.jsonStr2obj(res.bodyString(), QiniuUploadResponse.class);
			}
			if (filePath instanceof File) {
				res = uploadManager.put((File) filePath, fileName, upToken);
				LOG.info("-七牛上传:{}", res.bodyString());
				resoponse = JSONTools.jsonStr2obj(res.bodyString(), QiniuUploadResponse.class);
			}
			if (filePath instanceof String) {
				res = uploadManager.put(filePath.toString(), fileName, upToken);
				LOG.info("-七牛上传:{}", res.bodyString());
				resoponse = JSONTools.jsonStr2obj(res.bodyString(), QiniuUploadResponse.class);
			}
			resoponse.setUrl(config.getFileDomain());
			return resoponse;
		} catch (QiniuException e) {
			Response r = e.response;
			// 请求失败时打印的异常的信息
			try {
				LOG.info("-七牛上传->失败:{}", r.bodyString());
				return null;
				// 响应的文本信息
			} catch (QiniuException e1) {
				return null;
				// ignore
			}
		}
	}

	// 普通删除
	public void delete(String key) {
		if (StringUtils.isEmpty(key))
			return;
		// 实例化一个BucketManager对象
		Configuration cfg = new Configuration(Region.region0());
		Auth auth = Auth.create(config.getAccessKey(), config.getSecretKey());
		BucketManager bucketManager = new BucketManager(auth, cfg);
		// 此处的33是去掉：http://ongsua0j7.bkt.clouddn.com/,剩下的key就是图片在七牛云的名称
		if (key.contains(config.fileDomain)) {
			key = key.substring(config.fileDomain.length());

			try {
				// 调用delete方法移动文件 Response r =
				bucketManager.delete(config.getBucketName(), key);
				// LOG.info("-七牛删除:{}", r.bodyString());
			} catch (QiniuException e) {
				// e.printStackTrace();
			}
		}
	}

	/**
	 * @作者：陳曉鬆 @时间：2020年6月12日 下午2:49:06 @版本：V1.0 @description：->根据前缀删除
	 */
	public Integer deleteByPrefix(String prefix) {
		if (StringUtils.isEmpty(prefix)) {
			return null;
		}
		int num = 0;
		prefix = prefix.replaceAll("\\\\", "/");

		Configuration cfg = new Configuration(Region.region0());
		Auth auth = connectQiniu();
		BucketManager bucketManager = new BucketManager(auth, cfg);
		/** 每次迭代的长度限制，最大1000，推荐值 1000 */
		int limit = 1000;
		/** 指定目录分隔符，列出所有公共前缀（模拟列出目录效果）。缺省值为空字符串 */
		String delimiter = "";
		/** 列举空间文件列表 */
		BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(config.getBucketName(), prefix, limit, delimiter);
		while (fileListIterator.hasNext()) {
			/** 处理获取的file list结果 */
			FileInfo[] items = fileListIterator.next();
			if (items == null) {
				return null;
			}
			long invalidTime = 24 * 60 * 60 * 1000;// 缓存保存1天之内的
			for (FileInfo item : items) {
				Long chaTime = System.currentTimeMillis() - item.putTime / 10000;
				if (chaTime > invalidTime) {
					try {
						bucketManager.delete(config.getBucketName(), item.key);
					} catch (QiniuException ex) {
						System.err.println(ex.response.toString());
					}
				}
			}
		}
		return num;
	}

	// 图片更改地址 非异步
	public String uploadImageUrl(String images) {
		String result = "";
		if (StringUtils.isEmpty(images)) {
			return result;
		}
		String str[] = (images + ",").split(",");
		for (String s : str) {
			if (StringUtils.isEmpty(s)) {
				continue;
			}
			if (!s.contains(PublicConstant.QINIU_CACHE_PATH)) {
				result += s + ",";
				continue;
			}
			if (!s.contains(config.getFileDomain())) {
				result += s + ",";
				continue;
			}
			try {
				String url = uploadUrlImage(s, s.replace(config.getFileDomain() + PublicConstant.QINIU_CACHE_PATH, ""));
				result += url + ",";
				delete(s);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (result.indexOf(",") != 0) {
			result = result.substring(0, result.length() - 1);
		}
		return result;
	}

	// 图片更改地址 异步
	@Async
	public void uploadImageUrlByAsync(String images) {
		if (StringUtils.isEmpty(images)) {
			return;
		}
		String str[] = (images + ",").split(",");
		for (String s : str) {
			if (StringUtils.isEmpty(s)) {
				continue;
			}
			if (!s.contains(PublicConstant.QINIU_CACHE_PATH)) {
				continue;
			}
			if (!s.contains(config.getFileDomain())) {
				continue;
			}
			try {
				uploadUrlImage(s, s.replace(config.getFileDomain() + PublicConstant.QINIU_CACHE_PATH, ""));
				delete(s);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @作者：陳曉鬆 @时间：2020年7月9日 上午9:36:22 @版本：V1.0 @description：-> 处理网页html
	 */
	public String dealHtml(String htmlContent, String path) {
		if (StringUtils.isEmpty(htmlContent)) {
			return null;
		}
		htmlContent = htmlContent.replace("\"", "'");
		Matcher m = Pattern.compile("src=\"?(.*?)(\"|>|\\s+)").matcher(htmlContent);
		while (m.find()) {
			try {
				String temp = m.group();
				String url = temp.substring(5, temp.length() - 2);
				String newUrl = null;
				if (url.contains("base64")) {
					String str[] = url.split(";");
					String fileName = path + DateUtils.DF_CLOSED.get().format(new Date()) + PublicMethod.getCode(10) + "." + str[0].split("/")[1];
					QiniuUploadResponse response = upload(org.apache.commons.codec.binary.Base64.decodeBase64(str[1].split(",")[1]), fileName);
					if (response == null) {
						continue;
					}
					newUrl = response.getUrl() + response.getKey();
				} else {
					newUrl = uploadImageUrl(url);
				}
				if (!StringUtils.isEmpty(newUrl) && !url.equals(newUrl)) {
					htmlContent = htmlContent.replace(url, newUrl);
				}
			} catch (Exception e) {
				LOG.error("-处理网页代码-出错->{},{}", m.group(), PublicMethod.printErrorTrace(e));
			}
		}
		htmlContent = htmlContent.replace("  ", "&nbsp;&nbsp;");
		return htmlContent;
	}

//	public static void main(String[] args) {
//		String str = new QiniuUtils().dealHtml("<p><img src='http://file.cqshuying.com/1/1/202008161739258115471973.png'></p>", "");
//		System.out.println(str);
//	}

}
